package com.unismc.charge.collector.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.gitee.loyo.data.*;
import com.gitee.loyo.post.NotifyChargeOrderInfoPost;
import com.gitee.loyo.post.NotifyEquipChargeStatusPost;
import com.gitee.loyo.result.QueryStationStatsResult;
import com.gitee.loyo.result.QueryStationStatusResult;
import com.gitee.loyo.result.QueryStationsResult;
import com.unismc.charge.collector.cache.ChargeInfoCache;
import com.unismc.charge.collector.constant.UviewChargeConst;
import com.unismc.charge.collector.service.PushService;
import com.unismc.transport.common.UviewMqttClient;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.event.EventListener;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.util.List;

/**
 * @author: Forward Seen
 * @description:
 * @createTime: 2024/4/28 11:13
 * @since: 1.0
 */
@Slf4j
@Service
public class PushServiceImpl implements PushService {

    @Resource
    private UviewMqttClient client;

    @Async
    @EventListener
    @Override
    public void pushStationInfos(QueryStationsResult stationsForm) {
        if (stationsForm == null) {
            return;
        }
        List<StationInfo> stationInfos = stationsForm.getStationInfos();
        for (StationInfo stationInfo : stationInfos) {
            pushStationInfo(stationInfo);
        }
    }

    @Async
    @EventListener
    @Override
    public void pushStationInfo(StationInfo stationInfo) {
        if (stationInfo == null) {
            return;
        }
        String deviceName = stationInfo.getStationId();
        client.createDevice(deviceName, UviewChargeConst.CONF_TYPE_STATION);
        JSONObject attrs = new JSONObject();
        attrs.put("stationId", stationInfo.getStationId());
        attrs.put("operatorId", stationInfo.getOperatorId());
        attrs.put("stationName", stationInfo.getStationName());
        attrs.put("equipmentOwnerId", stationInfo.getEquipmentOwnerId());
        attrs.put("countryCode", stationInfo.getCountryCode());
        attrs.put("areaCode", stationInfo.getAreaCode());
        attrs.put("address", stationInfo.getAddress());
        attrs.put("stationTel", stationInfo.getStationTel());
        attrs.put("stationType", stationInfo.getStationType());
        attrs.put("stationStatus", stationInfo.getStationStatus());
        attrs.put("parkNums", stationInfo.getParkNums());
        attrs.put("stationLng", stationInfo.getStationLng());
        attrs.put("stationLat", stationInfo.getStationLat());
        attrs.put("siteGuide", stationInfo.getSiteGuide());
        attrs.put("construction", stationInfo.getConstruction());
        attrs.put("pictures", stationInfo.getPictures());
        attrs.put("matchCars", stationInfo.getMatchCars());
        attrs.put("parkInfo", stationInfo.getParkInfo());
        attrs.put("busineHours", stationInfo.getBusineHours());
        attrs.put("electricityFee", stationInfo.getElectricityFee());
        attrs.put("serviceFee", stationInfo.getServiceFee());
        attrs.put("parkFee", stationInfo.getParkFee());
        attrs.put("payment", stationInfo.getPayment());
        attrs.put("supportOrder", stationInfo.getSupportOrder());
        attrs.put("remark", stationInfo.getRemark());
        client.sendAttr(deviceName, attrs);
        List<EquipmentInfo> equipmentInfos = stationInfo.getEquipmentInfos();
        if (CollectionUtils.isEmpty(equipmentInfos)) {
            return;
        }
        for (EquipmentInfo equipmentInfo : equipmentInfos) {
            pushEquipmentInfo(equipmentInfo);
        }
    }

    @Async
    @Override
    public void pushEquipmentInfo(EquipmentInfo equipmentInfo) {
        if (equipmentInfo == null) {
            return;
        }
        String deviceName = equipmentInfo.getEquipmentId();
        client.createDevice(deviceName, UviewChargeConst.CONF_TYPE_EQUIPMENT);
        JSONObject attrs = new JSONObject();
        attrs.put("equipmentId", equipmentInfo.getEquipmentId());
        attrs.put("equipmentName", equipmentInfo.getEquipmentName());
        attrs.put("manufacturerId", equipmentInfo.getManufacturerId());
        attrs.put("manufacturerName", equipmentInfo.getManufacturerName());
        attrs.put("equipmentModel", equipmentInfo.getEquipmentModel());
        attrs.put("productionDate", equipmentInfo.getProductionDate());
        attrs.put("equipmentType", equipmentInfo.getEquipmentType());
        attrs.put("equipmentLng", equipmentInfo.getEquipmentLng());
        attrs.put("equipmentLat", equipmentInfo.getEquipmentLat());
        attrs.put("power", equipmentInfo.getPower());
        attrs.putAll(ChargeInfoCache.getEquipmentBaseInfo(deviceName));
        client.sendAttr(deviceName, attrs);
        List<ConnectorInfo> connectorInfos = equipmentInfo.getConnectorInfos();
        if (CollectionUtils.isEmpty(connectorInfos)) {
            return;
        }
        for (ConnectorInfo connectorInfo : connectorInfos) {
            pushConnectorInfo(connectorInfo);
        }
    }

    @Async
    @Override
    public void pushConnectorInfo(ConnectorInfo connectorInfo) {
        if (connectorInfo == null) {
            return;
        }
        String deviceName = connectorInfo.getConnectorId();
        client.createDevice(deviceName, UviewChargeConst.CONF_TYPE_CONNECTOR);
        JSONObject attrs = new JSONObject();
        attrs.put("connectorId", connectorInfo.getConnectorId());
        attrs.put("connectorName", connectorInfo.getConnectorName());
        attrs.put("connectorType", connectorInfo.getConnectorType());
        attrs.put("voltageUpperLimits", connectorInfo.getVoltageUpperLimits());
        attrs.put("voltageLowerLimits", connectorInfo.getVoltageLowerLimits());
        attrs.put("current", connectorInfo.getCurrent());
        attrs.put("power", connectorInfo.getPower());
        attrs.put("parkNo", connectorInfo.getParkNo());
        attrs.put("nationalStandard", connectorInfo.getNationalStandard());
        attrs.putAll(ChargeInfoCache.getConnectorBaseInfo(deviceName));
        client.sendAttr(deviceName, attrs);
    }

    @Async
    @EventListener
    @Override
    public void pushStationsStatus(QueryStationStatusResult stationsStatus) {
        if (stationsStatus == null) {
            return;
        }
        List<StationStatusInfo> stationStatusInfos = stationsStatus.getStationStatusInfos();
        for (StationStatusInfo stationStatusInfo : stationStatusInfos) {
            pushStationStatus(stationStatusInfo);
        }
    }

    @Async
    @EventListener
    @Override
    public void pushStationStatus(StationStatusInfo stationStatus) {
        if (stationStatus == null) {
            return;
        }
        List<ConnectorStatusInfo> connectorStatusInfos = stationStatus.getConnectorStatusInfos();
        if (CollectionUtils.isEmpty(connectorStatusInfos)) {
            return;
        }
        for (ConnectorStatusInfo connectorStatusInfo : connectorStatusInfos) {
            pushConnectorStatus(connectorStatusInfo);
        }
    }

    @Async
    @EventListener
    @Override
    public void pushConnectorStatus(ConnectorStatusInfo connectorStatus) {
        if (connectorStatus == null) {
            return;
        }
        String deviceName = connectorStatus.getConnectorId();
        JSONObject msg = new JSONObject();
        msg.put("status", connectorStatus.getStatus());
        msg.put("parkStatus", connectorStatus.getParkStatus());
        msg.put("lockStatus", connectorStatus.getLockStatus());
        client.send(deviceName, msg);
    }

    @Async
    @EventListener
    @Override
    public void pushStationsStats(QueryStationStatsResult stationsStatus) {
        if (stationsStatus == null) {
            return;
        }
        StationStatsInfo stationStats = stationsStatus.getStationStats();
        pushStationStats(stationStats);
    }

    @Async
    @EventListener
    @Override
    public void pushStationStats(StationStatsInfo stationStats) {
        if (stationStats == null) {
            return;
        }
        String deviceName = stationStats.getStationId();
        JSONObject msg = new JSONObject();
        msg.put("startTime", stationStats.getStartTime());
        msg.put("endTime", stationStats.getEndTime());
        msg.put("stationElectricity", stationStats.getStationElectricity());
        client.send(deviceName, msg);
        List<EquipmentStatsInfo> equipmentStatsInfos = stationStats.getEquipmentStatsInfos();
        if (CollectionUtils.isEmpty(equipmentStatsInfos)) {
            return;
        }
        for (EquipmentStatsInfo equipmentStatsInfo : equipmentStatsInfos) {
            pushEquipmentStats(equipmentStatsInfo);
        }
    }

    @Async
    @EventListener
    @Override
    public void pushEquipmentStats(EquipmentStatsInfo equipmentStats) {
        if (equipmentStats == null) {
            return;
        }
        String deviceName = equipmentStats.getEquipmentId();
        JSONObject msg = new JSONObject();
        msg.put("equipmentElectricity", equipmentStats.getEquipmentElectricity());
        client.send(deviceName, msg);
        List<ConnectorStatsInfo> connectorStatsInfos = equipmentStats.getConnectorStatsInfos();
        for (ConnectorStatsInfo connectorStatsInfo : connectorStatsInfos) {
            pushConnectorStats(connectorStatsInfo);
        }
    }

    @Async
    @EventListener
    @Override
    public void pushConnectorStats(ConnectorStatsInfo connectorStats) {
        if (connectorStats == null) {
            return;
        }
        String deviceName = connectorStats.getConnectorId();
        JSONObject msg = new JSONObject();
        msg.put("connectorElectricity", connectorStats.getConnectorElectricity());
        client.send(deviceName, msg);
    }

    @Async
    @EventListener
    @Override
    public void pushChargeStatus(NotifyEquipChargeStatusPost chargeStatus) {
        if (chargeStatus == null) {
            return;
        }
        String deviceName = chargeStatus.getConnectorId();
        JSONObject msg = new JSONObject();
        msg.put("startChargeSeq", chargeStatus.getStartChargeSeq());
        msg.put("startChargeSeqStat", chargeStatus.getStartChargeSeqStat());
        msg.put("connectorStatus", chargeStatus.getConnectorStatus());
        msg.put("currentA", chargeStatus.getCurrentA());
        msg.put("currentB", chargeStatus.getCurrentB());
        msg.put("currentC", chargeStatus.getCurrentC());
        msg.put("voltageA", chargeStatus.getVoltageA());
        msg.put("voltageB", chargeStatus.getVoltageB());
        msg.put("voltageC", chargeStatus.getVoltageC());
        msg.put("soc", chargeStatus.getSoc());
        msg.put("startTime", chargeStatus.getStartTime());
        msg.put("endTime", chargeStatus.getEndTime());
        msg.put("totalPower", chargeStatus.getTotalPower());
        msg.put("elecMoney", chargeStatus.getElecMoney());
        msg.put("serviceMoney", chargeStatus.getServiceMoney());
        msg.put("totalMoney", chargeStatus.getTotalMoney());
        msg.put("sumPeriod", chargeStatus.getSumPeriod());
        msg.put("chargeDetails", chargeStatus.getChargeDetails());
        client.send(deviceName, msg);
    }

    @Async
    @EventListener
    @Override
    public void pushChargeOrderInfo(NotifyChargeOrderInfoPost chargeOrderInfo) {
        if (chargeOrderInfo == null) {
            return;
        }
        String deviceName = chargeOrderInfo.getConnectorId();
        JSONObject msg = new JSONObject();
        msg.put("startChargeSeq", chargeOrderInfo.getStartChargeSeq());
        msg.put("startTime", chargeOrderInfo.getStartTime());
        msg.put("endTime", chargeOrderInfo.getEndTime());
        msg.put("totalPower", chargeOrderInfo.getTotalPower());
        msg.put("totalElecMoney", chargeOrderInfo.getTotalElecMoney());
        msg.put("totalServiceMoney", chargeOrderInfo.getTotalServiceMoney());
        msg.put("totalMoney", chargeOrderInfo.getTotalMoney());
        msg.put("stopReason", chargeOrderInfo.getStopReason());
        msg.put("chargeDetails", chargeOrderInfo.getChargeDetails());
        client.send(deviceName, msg);
    }

}
